home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Human Interface Toolbox / ColorPopUpMenus / ColorPopUpMenus.c next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  7.5 KB  |  243 lines  |  [TEXT/MPS ]

  1. /*
  2.     File: ColorPopUpMenus.c
  3.  
  4.     Contains:    This file contains an example illustrating how to show swatches
  5.     of color in a labels-like menu in your own application.  It also illustrates
  6.     how to add a user adjustable color item to the menu that can be changed by
  7.     way of the color picker interface.
  8.     
  9.     Behind the scenes, the color swatches in the menu are implemented as color
  10.     icon resources.  The only real tricky part here is finding the correct place
  11.     to save the color in the color icon resource.  And, two routines have been
  12.     provided that do just that. 
  13.  
  14.     Written by: John Montbriand
  15.  
  16.     Copyright:    Copyright © 1999 by Apple Computer, Inc., All Rights Reserved.
  17.  
  18.     You may incorporate this Apple sample source code into your program(s) without
  19.     restriction. This Apple sample source code has been provided "AS IS" and the
  20.     responsibility for its operation is yours. You are not permitted to redistribute
  21.     this Apple sample source code as "Apple sample source code" after having made
  22.     changes. If you're going to re-distribute the source, we require that you make
  23.     it clear in the source that the code was descended from Apple sample source
  24.     code, but that you've made changes.
  25.  
  26.     Change History (most recent first):
  27.     7/19/1999 Karl Groethe - Updated for Metrowerks Codewarror Pro 2.1
  28.     10/7/1999 John Montbriand - removed bad menu resource definition, rewrote the rest :)
  29. */
  30.  
  31. #include "ColorPopUpMenus.h"
  32.  
  33. #include <Dialogs.h>
  34. #include <Fonts.h>
  35. #include <Sound.h>
  36. #include <Resources.h>
  37. #include <ColorPicker.h>
  38. #include <Icons.h>
  39. #include <Errors.h>
  40. #include <StdDef.h>
  41.  
  42.  
  43. #ifndef __MWERKS__
  44. QDGlobals    qd; /* QuickDraw globals */
  45. #endif
  46.  
  47.  
  48.     /* gUserSelectColor is our internal copy of the user adjustable
  49.     color.  The adjustable item is initially set to this value, and
  50.     it can be adjusted by the user when ever they choose the 'Other...'
  51.     item in the pop-up menu. */
  52. RGBColor gUserSelectColor = { 0xACAC, 0xACAC, 0xACAC };
  53.  
  54.  
  55.     /* gUserSelectColorIcon is a handle to color icon that is used
  56.     to display the user adjustable color swatch in the 'Other...'
  57.     item in the pop-up menu. */
  58. CIconHandle gUserSelectColorIcon = NULL;
  59.  
  60.  
  61.  
  62.  
  63.  
  64. /* ChangeCIconIXColor changes the index'th color in the
  65.     color icon's clut to *color. if index is out of range, then
  66.     paramErr is returned.  It'll work for any size color
  67.     icon. */
  68.     
  69. static OSErr ChangeCIconIXColor(CIconHandle cicn, short index, RGBColor *color) {
  70.     unsigned char *rover;
  71.     CTabPtr clutp;
  72.     char state;
  73.     OSErr err;
  74.  
  75.         /* make sure it's in memory */
  76.     LoadResource((Handle) cicn);
  77.     if ((err = ResError()) != noErr) return err;
  78.  
  79.         /* lock down the handle, we're making toolbox calls while
  80.         using a pointer to some of it's contents.  We may know that
  81.         routine probably doesn't move memory, but it's always best
  82.         to take a conservative position.  */
  83.     state = HGetState((Handle) cicn);
  84.     HLock((Handle) cicn);
  85.     
  86.         /* increment to the clut in the cicn resource.  see GetCIconIXColor
  87.         for the book reference for the format spec. */
  88.     rover = ((unsigned char *) (*cicn)) + offsetof(CIcon, iconMaskData);
  89.     rover += (**cicn).iconMask.rowBytes * (**cicn).iconMask.bounds.bottom;
  90.     rover += (**cicn).iconBMap.rowBytes * (**cicn).iconBMap.bounds.bottom;
  91.     clutp = (CTabPtr) rover;
  92.     
  93.         /* check to make sure the index is in range */
  94.     if ((index < 0) || (index > clutp->ctSize)) {
  95.             /* index out of range */
  96.         err = paramErr;
  97.     } else {
  98.             /* set the clut entry */
  99.         clutp->ctTable[index].rgb = *color;
  100.             
  101.             /* reset the ctSeed value so QuickDraw with identify
  102.             the color table as 'unique'. */
  103.         clutp->ctSeed = GetCTSeed();
  104.         
  105.             /* no problem...*/
  106.         err = noErr;
  107.     }
  108.         
  109.         /* restore the resource handle's state */
  110.     HSetState((Handle) cicn, state);
  111.     
  112.         /* done */
  113.     return err;
  114. }
  115.  
  116.  
  117.  
  118.  
  119. /* GetCIconIXColor retrieves the index'th color from the
  120.     color icon's clut.  if index is out of range, then paramErr is returned.
  121.     
  122.     This routine isn't used in this example, but I added it as a
  123.     symetrical counterpart to ChangeCIconIXColor incase someone might
  124.     find it useful.  Normally, the UI will only reflect the state
  125.     of your program's internal state variables so there's no need
  126.     to query the interface elements for values being displayed. */
  127.     
  128. static OSErr GetCIconIXColor(CIconHandle cicn, short index, RGBColor *color) {
  129.     unsigned char *rover;
  130.     CTabPtr clutp;
  131.     OSErr err;
  132.     
  133.         /* make sure it's in memory */
  134.     LoadResource((Handle) cicn);
  135.     if ((err = ResError()) != noErr) return err;
  136.     
  137.         /* find the color table inside of the cicn resource.
  138.         The resource we're using in this example has a two
  139.         element color table.  Here, we're incrementing a
  140.         pointer past the structures in the cicn resource.
  141.         This structure is defined in the Color QuickDraw
  142.         chapter of Inside Macintosh.  That page can be
  143.         found on the web at:
  144.             http://developer.apple.com/techpubs/mac/QuickDraw/QuickDraw-268.html.  */
  145.     rover = ((unsigned char *) (*cicn)) + offsetof(CIcon, iconMaskData);
  146.     rover += (**cicn).iconMask.rowBytes * (**cicn).iconMask.bounds.bottom;
  147.     rover += (**cicn).iconBMap.rowBytes * (**cicn).iconBMap.bounds.bottom;
  148.     clutp = (CTabPtr) rover;
  149.     
  150.         /* check the index range */
  151.     if ((index < 0) || (index > clutp->ctSize)) return paramErr;
  152.     
  153.         /* save the color */
  154.     *color = clutp->ctTable[index].rgb;
  155.     
  156.         /* done */
  157.     return noErr;
  158. }
  159.  
  160.  
  161.  
  162.  
  163.  
  164.  
  165.     /* main program.  Here, we put up a modal dialog.  When ever
  166.     the user picks the configurable color item in the menu, we
  167.     put up the color picker to allow them to adjust the color. */
  168.  
  169.  
  170. int main (void) {
  171.     DialogPtr dialog;
  172.     short itemHit;
  173.  
  174.         /* set up the managers */
  175.     MaxApplZone();
  176.     InitGraf(&qd.thePort);
  177.     InitFonts();
  178.     InitWindows();
  179.     InitMenus();
  180.     TEInit();
  181.     InitDialogs(NULL);
  182.  
  183.         /* set up the user adjustable color swatch.  We'll
  184.         initially set the color displayed to our own default
  185.         color setting. Note, we call 'GetResource' instead
  186.         of 'GetCIcon'.  When the control is created in the 
  187.         GetNewDialog call, GetCIcon will be called. */
  188.     gUserSelectColorIcon = (CIconHandle) GetResource('cicn', kOtherIconRsrc);
  189.     if (gUserSelectColorIcon == NULL) return 1;
  190.     ChangeCIconIXColor(gUserSelectColorIcon, kOutClutColorIndex, &gUserSelectColor);
  191.  
  192.         /* call up the dialog containing our color choice menu. */
  193.     dialog = GetNewDialog(kMainDialog,nil,nil);
  194.     if (dialog == NULL) return 1;
  195.     SetDialogTracksCursor(dialog, true);
  196.     SetDialogDefaultItem(dialog, kMainOK);
  197.  
  198.  
  199.         /* loop and process dialog events */
  200.     do {
  201.         
  202.         ModalDialog(NULL, &itemHit);
  203.         
  204.             /* check to see if it's a hit in the menu item */
  205.         if (itemHit == kMainPopUp) {
  206.             short itemt;
  207.             ControlHandle itemc;
  208.             Rect itemb;
  209.             RGBColor inColor, outColor;
  210.             Point pickerWhere = { -1, -1 };
  211.             
  212.                 /* it's a hit in the menu, now test to see if the
  213.                 adjustable color item was selected */
  214.             GetDialogItem(dialog, kMainPopUp, &itemt, (Handle *) &itemc, &itemb);
  215.             if (GetControlValue(itemc) == kMainPopUpOtherItem) {
  216.                 
  217.                     /* let the user adjust the color for this item */
  218.                 inColor = outColor = gUserSelectColor;
  219.                 if (GetColor(pickerWhere, "\pPick a color for the menu item.", &inColor, &outColor)) {
  220.                     
  221.                         /* if they didn't cancel out of the color picker window,
  222.                         then save the color back in to our global. */
  223.                     gUserSelectColor = outColor;
  224.                     
  225.                         /* ...then save the color back into the icon's color
  226.                         table. */
  227.                     ChangeCIconIXColor(gUserSelectColorIcon, kOutClutColorIndex, &gUserSelectColor);
  228.  
  229.                         /* ...and finally, redraw the control.  This will
  230.                         redraw the menu in the control, which, in turn,
  231.                         will redraw the color icon with it's new color setting.*/
  232.                     Draw1Control(itemc);
  233.                 }
  234.             }
  235.         }
  236.  
  237.     } while (itemHit != kMainOK);
  238.             
  239.         /* clean up and leave */
  240.     DisposeDialog (dialog);
  241.     return 0;
  242. }
  243.